package com.example.mymusicdisplay.data.lrc;

import android.text.TextUtils;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.util.Log;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 歌词解析基类
 */
public class LrcEntity implements Comparable<LrcEntity> {
    private static final String TAG = "LrcEntity";
    public String time;
    public long timeLong;
    public String text;

    private static final String LINE_REGEX = "((\\[\\d{2}:\\d{2}\\.\\d{1,3}])+)(.*)";
    private static final String TIME_REGEX = "\\[(\\d{2}):(\\d{2})\\.(\\d{1,3})]";

    public LrcEntity() {
    }

    public LrcEntity(String time, String text, long timeLong) {
        this.time = time;
        this.text = text;
        this.timeLong = timeLong;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public long getTimeLong() {
        return timeLong;
    }

    public void setTimeLong(long timeLong) {
        this.timeLong = timeLong;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    @Override
    public int compareTo(LrcEntity entity) {
        if (entity == null) {
            return -1;
        }
        return (int) (timeLong - entity.getTimeLong());
    }

    @Override
    public String toString() {
        return "LrcEntity{" +
                "time='" + time + '\'' +
                ", timeLong=" + timeLong +
                ", text='" + text + '\'' +
                '}';
    }

    /**
     * 解析歌词文本
     *
     * @param lrcText
     * @return
     */
    public static List<LrcEntity> parseLrc(String lrcText) {
        if (TextUtils.isEmpty(lrcText)) {
            return null;
        }

        List<LrcEntity> entityList = new ArrayList<>();
        // 将字符串以换行符切割
        String[] array = lrcText.split("\\n");
        for (String line : array) {
            // 循环遍历按行解析
            List<LrcEntity> list = parseLine(line);
            if (list != null && !list.isEmpty()) {
                entityList.addAll(list);
            }
        }

        // 使序列按大小升序排序（由小到大）
        Collections.sort(entityList);
        return entityList;
    }

    /**
     * 针对每一句歌词解析，并存到LrcEntity中
     *
     * @param line
     * @return
     */
    private static List<LrcEntity> parseLine(String line) {
        if (TextUtils.isEmpty(line)) {
            return null;
        }
        // 去除空格
        line = line.trim();
        if (line.startsWith("[ti:")) {
            String title = line.substring(4, line.length() - 1);
            List<LrcEntity> lrcEntities = new ArrayList<>();
            lrcEntities.add(new LrcEntity("[00:00.00]", "主题: " + title, 10));
            return lrcEntities;
        }//        //取得歌手信息
        else if (line.startsWith("[ar:")) {
            String artist = line.substring(4, line.length() - 1);
            List<LrcEntity> lrcEntities = new ArrayList<>();
            lrcEntities.add(new LrcEntity("[00:00.01]", "歌手: " + artist, 10));
            return lrcEntities;
        }
        //取得专辑信息
        else if (line.startsWith("[al:")) {
            String album = line.substring(4, line.length() - 1);
            List<LrcEntity> lrcEntities = new ArrayList<>();
            lrcEntities.add(new LrcEntity("[00:00.02]", "专辑: " + album, 10));
            return lrcEntities;
        }
        //取得歌词制作者
        else if (line.startsWith("[by:")) {
            String bySomeBody = line.substring(4, line.length() - 1);
            List<LrcEntity> lrcEntities = new ArrayList<>();
            lrcEntities.add(new LrcEntity("[00:00.03]", "作词: " + bySomeBody, 10));
            return lrcEntities;
        } else if (line.startsWith("[offset:")) {
            String time = line.substring(8, line.length() - 1);
            long timeLong = Long.parseLong(time);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss.SS");
            Date date = new Date(timeLong);
            List<LrcEntity> lrcEntities = new ArrayList<>();
            Log.d(TAG, "parseLine: simpleDateFormat.format(date) = " + simpleDateFormat.format(date));
            lrcEntities.add(new LrcEntity("[" + simpleDateFormat.format(date) + "]", "", timeLong));
            return lrcEntities;
        }
        // 正则表达式，判断line中是否有[01:10.60]格式的片段
        //Matcher lineMatcher = Pattern.compile("((\\[\\d\\d:\\d\\d\\.\\d\\d\\])+)(.+)").matcher(line);
        Matcher lineMatcher = Pattern.compile(LINE_REGEX).matcher(line);
        // 如果没有，返回null
        if (!lineMatcher.matches()) {
            return null;
        }

        // 得到时间标签
        String times = lineMatcher.group(1);
        // 得到文本内容
        String text = lineMatcher.group(3);
        List<LrcEntity> entryList = new ArrayList<>();

        //Matcher timeMatcher = Pattern.compile("\\[(\\d\\d):(\\d\\d)\\.(\\d\\d)\\]").matcher(times);
        Matcher timeMatcher = Pattern.compile(TIME_REGEX).matcher(times);
        while (timeMatcher.find()) {
            long min = Long.parseLong(timeMatcher.group(1));// 分
            long sec = Long.parseLong(timeMatcher.group(2));// 秒
            long mil = Long.parseLong(timeMatcher.group(3));// 毫秒
            // 得到long型时间
            String thisTime = "[" + timeMatcher.group(1) + ":" + timeMatcher.group(2) + "." + timeMatcher.group(3) + "]";
            long time;
            if (String.valueOf(mil).length() == 3) {
                time = min * DateUtils.MINUTE_IN_MILLIS + sec * DateUtils.SECOND_IN_MILLIS + mil ;
            } else {
                time = min * DateUtils.MINUTE_IN_MILLIS + sec * DateUtils.SECOND_IN_MILLIS + mil* 10;
            }
            // 最终解析得到一个list
            LrcEntity lrcEntity = new LrcEntity(thisTime, text, time);
            entryList.add(lrcEntity);
        }
        return entryList;
    }

    public static String formatTime(long time) {
        int min = (int) (time / 60000);
        int sec = (int) (time / 1000 % 60);
        return adjustFormat(min) + ":" + adjustFormat(sec);
    }

    private static String adjustFormat(int time) {
        if (time < 10) {
            return "0" + time;
        }
        return time + "";
    }
}